#include <iostream>
#include <string>
#include <vector>
#include <chrono>
#include <thread>

#include <sw/redis++/redis++.h>

#include "util.hpp"

using std::cout;
using std::endl;
using std::string;
using std::vector;

namespace redis = sw::redis;

void test_lpush_and_lrange(redis::Redis& redis){
    cout << "lpush and lrange" << endl;
    redis.flushall();

    // 头插数据
    // 插入单个元素
    redis.lpush("key1", "111");
    // 一次性插入多个
    redis.lpush("key1", {"222", "333", "444"});
    // 使用容器，迭代器插入
    vector<string> nums = {"555", "666", "777"};
    redis.lpush("key1", nums.begin(), nums.end());
    // 获取数据
    vector<string> res;
    auto it = std::back_inserter(res);
    redis.lrange("key1", 0, -1, it);

    printContainer(res);
}

void test_rpush_and_pop(redis::Redis& redis){
    cout << "rpush and pop" << endl;
    redis.flushall();

    // 尾插数据
    // 插入单个元素
    redis.rpush("key1", "111");
    // 一次性插入多个
    redis.rpush("key1", {"222", "333", "444"});
    // 使用容器，迭代器插入
    vector<string> nums = {"555", "666", "777"};
    redis.rpush("key1", nums.begin(), nums.end());

    // 获取数据
    vector<string> res;
    auto it = std::back_inserter(res);
    redis.lrange("key1", 0, -1, it);
    printContainer(res);

    // 头删数据
    auto value = redis.lpop("key1");
    if(value){
        cout << "头删数据: " << value.value() << endl;
    }

    // 尾删数据
    value = redis.rpop("key1");
    if(value){
        cout << "尾删数据: " << value.value() << endl;
    }

    // 获取list长度
    auto len = redis.llen("key1");
    cout << "len: " << len << endl;
}


void test_blpop_and_brpop(redis::Redis& redis){
    cout << "blpop" << endl;
    redis.flushall();

    redis.lpush("key1", {"111", "222", "333"});
    redis.lpush("key2", {"444", "555", "666"});
    redis.lpush("key3", {"777", "888", "999"});

    // 阻塞获取数据
    // 可以指定一个或多个key
    // 不设置超时时间就是一直阻塞

    // auto res = redis.blpop("key4", std::chrono::seconds(20));
    auto res = redis.brpop({"key1", "key2", "key3"});
    // 返回值是 option, 里面是一个pair<string, string>
    // first 是 被弹出的 key, second 是 被弹出的value
    if(res){
        // cout << "key: " << res.value().first << endl;
        // cout << "value: " << res.value().second << endl;
        // 也可以
        cout << "key: " << res->first << endl;
        cout << "value: " << res->second << endl;
    }
    else{
        cout << "超时，没有数据" << endl;
    }
}

int main(){
    redis::Redis redis("tcp://666666@127.0.0.1:6379");

    // test_lpush_and_lrange(redis);
    // test_rpush_and_pop(redis);
    test_blpop_and_brpop(redis);


    return 0;
}
